package com.erp.base.base;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;

import com.fasterxml.jackson.annotation.JsonIgnore;

public class Page<T> {
	protected long offset = 0; // 当前页码
	protected int limit = -1; // 页面大小，设置为“-1”表示不进行分页（分页无效） 
	protected long total;// 总记录数，设置为“-1”表示不查询总数 
	private List<T> rows = new ArrayList<T>();
	private String orderBy = ""; // 标准查询有效， 实例： updatedate desc
	
	public Page() {
	} 
	 
	/**
	 * 构造方法
	 * @param pageNo 当前页码
	 * @param pageSize 分页大小
	 */
	public Page(long offset, int limit) {
		this(offset, limit, 0);
	}
	
	/**
	 * 构造方法
	 * @param pageNo 当前页码
	 * @param pageSize 分页大小
	 * @param count 数据条数
	 */
	public Page(long offset, int limit, long total) {
		this.offset=offset;
		this.limit=limit;
		this.total=total;
	}
	
	/**
	 * 构造方法
	 * @param pageNo 当前页码
	 * @param pageSize 分页大小
	 * @param count 数据条数
	 * @param list 本页数据对象列表
	 */
	public Page(long offset, int limit, long total, List<T> rows) {
		this(offset, limit, total);
		this.rows = rows;
	}
	
	 

	/**
	 * 获取设置总数
	 * @return
	 */
	public long getTotal() {
		return total;
	}

	/**
	 * 设置数据总数
	 * @param count
	 */
	public void setTotal(long total) {
		this.total = total;
		if (limit >= total){
			offset = 0;
		}
	} 
 
	
	/**
	 * 获取本页数据对象列表
	 * @return List<T>
	 */
	public List<T> getRows() {
		return rows;
	}

	/**
	 * 设置本页数据对象列表
	 * @param list
	 */
	public Page<T> setRows(List<T> rows) {
		this.rows = rows; 
		return this;
	}

	/**
	 * 获取查询排序字符串
	 * @return
	 */
	@JsonIgnore
	public String getOrderBy() {
		// SQL过滤，防止注入 
		String reg = "(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|"
					+ "(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)\\b)";
		Pattern sqlPattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);
		if (sqlPattern.matcher(orderBy).find()) {
			return "";
		}
		return orderBy;
	}

	/**
	 * 设置查询排序，标准查询有效， 实例： updatedate desc, name asc
	 */
	public void setOrderBy(String orderBy) {
		this.orderBy = orderBy;
	}
  
	/**
	 * 分页是否有效
	 * @return this.pageSize==-1
	 */
	@JsonIgnore
	public boolean isDisabled() {
		return this.limit==-1;
	}

	public long getOffset() {
		return offset;
	}

	public void setOffset(long offset) {
		this.offset = offset;
	}

	public int getLimit() {
		return limit;
	}

	public void setLimit(int limit) {
		this.limit = limit;
	}  
	
	public static <T> Page<T> bootstrapPage(HttpServletRequest request, HttpServletResponse response){
		Page<T> page=new Page<T>();
		String offset = request.getParameter("offset");
		String limit = request.getParameter("limit");
		if(StringUtils.isNotBlank(offset)){
			page.offset=Long.parseLong(offset);
		}
		if(StringUtils.isNotBlank(limit)){
			page.limit=Integer.parseInt(limit);
		} 
		// 设置排序参数 
		String order = request.getParameter("order");
		String sort = request.getParameter("sort");
		
		if (StringUtils.isNotBlank(order) && StringUtils.isNotBlank(sort)){
			//edit by chenchao
			//原来只有以下两句：
			/*
			 * String[] camelStrs=StringUtils.splitByCharacterTypeCamelCase(sort);
			 * page.setOrderBy(StringUtils.join(camelStrs,'_')+" "+order);
			 */
			if(!sort.contains("_")){
				// 此处添加字段名称转换，将可能出现的驼峰转换为下划线
				String[] camelStrs=StringUtils.splitByCharacterTypeCamelCase(sort);
				page.setOrderBy(StringUtils.join(camelStrs,'_')+" "+order);
			}
			else {
				page.setOrderBy(sort + " " + order);
			}
		}
		return page;
	}
	public static <T> Page<T> erpPage(HttpServletRequest request){
		Page<T> page=new Page<T>();
		String offset = request.getHeader("offset");
		String limit = request.getHeader("limit");
		if(StringUtils.isNotBlank(offset)){
			page.offset=Long.parseLong(offset);
		}
		if(StringUtils.isNotBlank(limit)){
			page.limit=Integer.parseInt(limit);
		} 
		return page;
	}
 
}
